<template>
	<view>
		<!-- 保留的按钮行 -->
		<view class="layout_horizontal" id="v1">
			<button class="button_sp" @click="goclear">清屏</button>
			<button class="button_sp">{{ connectState }}</button>
			<button class="button_sp" @click="godisconnect">{{ reconnect }}</button>
			<button class="button_sp" @click="gotoback">返回</button>
		</view>
		<!-- 充值界面 -->
		<view class="recharge">
			<view class="recharge-input">
				<input class="inputView" placeholder="请输入" v-model="rechargeAmount" />
			</view>
			<view class="recharge-buttons">
				<button class="recharge-button" :class="{ selected: rechargeAmount === '30' }"
					@click="setRechargeAmount(30)">
					30
				</button>
				<button class="recharge-button" :class="{ selected: rechargeAmount === '50' }"
					@click="setRechargeAmount(50)">
					50
				</button>
				<button class="recharge-button" :class="{ selected: rechargeAmount === '100' }"
					@click="setRechargeAmount(100)">
					100
				</button>
				<button class="recharge-button" :class="{ selected: rechargeAmount === '200' }"
					@click="setRechargeAmount(200)">
					200
				</button>
			</view>
		</view>
		<!-- 控制按钮 -->
		<!-- <view class="btn-controll">
		<button class="leftBtn" :disabled="sending" @click="sendOpen">开</button>
		<button class="rightBtn" :disabled="sending" @click="sendClose">关</button>
	  </view> -->
		<!-- 测试按钮 -->
		<!-- 测试： -->
		<view class="btn-controll">
			<button class="leftBtn" :disabled="sending" @click="blueOpen">开</button>
			<button class="rightBtn" :disabled="sending" @click="blueClose">关</button>
		</view>
		<!-- Loading 和 Modal -->
		<view v-if="loading" class="loading-overlay">
			<view class="loading-spinner"></view>
		</view>
		<view v-if="showModalStatus" class="modal-mask" @click="hideModalTips">
			<view class="modal-dialog">
				<view class="modal-title">提示</view>
				<view class="modal-content">{{ showTips }}</view>
				<view class="modal-footer">
					<view class="btn-cancel" @click="hideModalTips">取消</view>
					<view class="btn-confirm" @click="hideModalTips">确认</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
import {
	ajax
} from "../../utils/request";

export default {
	data() {
		return {
			device: null,
			connected: false,
			readyRec: false,
			hexSend: true,
			hexRec: true,
			deviceadd: " ",
			recdata: "",
			rxCount: 0,
			txCount: 0,
			rxRate: 0,
			txRate: 0,
			connectState: "正在连接",
			reconnect: "连接中...",
			timRX: 0,
			timTX: 0,
			sendText: "",
			autoSendInv: 50,
			autosendEn: false,
			autosendText: "自动发送",
			showModal: false,
			showModalStatus: false,
			showTips: "",
			deviceId: "",
			autoTimer: null,
			rechargeAmount: "",
			serviceu: "", // Service UUID
			txdu: "", // TX Characteristic UUID
			rxdu: "", // RX Characteristic UUID
			serviceId: "",
			characteristicId: "",
			sending: false,
			loading: false,
			bluetoothSwitch: false,
			hexadecimal: "",
			signal: "",
		};
	},
	methods: {
		blueOpen() {
			this.getBluetoothSignal("/api/meter/BluetoothOn");
		},
		blueClose() {
			this.getBluetoothSignal("/api/meter/BluetoothOff");
		},
		getBluetoothSignal(api) {
			ajax(api, "POST", {
				userId: "3",
				ss_mc: "13-A101",
			})
				.then((res) => {
					this.signal = res.data.hexAll;
					// if (uni.getSystemInfoSync().platform == 'ios') {
					// 	// 这是 iOS 平台特有的代码
					// 	console.log('这段代码只在 iOS 上运行');
					// 	//16进制转32进制
					// 	this.signal = this.hexTo32(this.signal);
					// 	console.log(this.signal);
					// }
					this.sendBluetoothSignal();
				})
				.catch((err) => {
					console.log(err);
				});
		},
		sendBluetoothSignal() {
			let uint8Array = new Uint8Array(this.signal.length / 2);
			for (let i = 0; i < this.signal.length; i += 2) {
				uint8Array[i / 2] = parseInt(this.signal.substr(i, 2), 16);
			}
			let buffer = uint8Array.buffer;

			setTimeout(() => {
				uni.writeBLECharacteristicValue({
					deviceId: this.deviceId,
					serviceId: this.serviceId,
					characteristicId: this.characteristicId,
					value: buffer,
					success: (res) => {
						this.txCount += buffer.byteLength;
						this.timTX += buffer.byteLength;
						uni.showToast({
							title: "发送成功",
							icon: "none"
						});
					},
					fail: (error) => {
						console.error("发送失败", error);
						uni.showToast({
							title: "发送失败",
							icon: "none"
						});
					},
					complete: () => {
						this.sending = false;
					},
				});
			}, 100);
		},
		goclear() {
			this.recdata = "";
			this.rxCount = 0;
			this.txCount = 0;
			this.rechargeAmount = "";
			this.sendText = "";
		},
		Countdown() {
			setTimeout(() => {
				this.rxRate = this.timRX * 2;
				this.txRate = this.timTX * 2;
				this.timRX = 0;
				this.timTX = 0;
				this.Countdown();
			}, 500);
		},
		sendOpen() {
			this.bluetoothSwitch = true;
			this.sendRechargeAmount();
		},
		sendClose() {
			this.bluetoothSwitch = false;
			this.sendRechargeAmount();
		},
		setRechargeAmount(amount) {
			this.rechargeAmount = amount.toString();
		},
		async sendRechargeAmount() {
			if (!this.rechargeAmount || !this.connected || this.sending) return;
			this.sending = true;
			this.hexadecimal = this.rechargeAmount;
			let sendToBlue = this.joint();
			this.sendText = sendToBlue;

			let uint8Array = new Uint8Array(sendToBlue.length / 2);
			for (let i = 0; i < sendToBlue.length; i += 2) {
				uint8Array[i / 2] = parseInt(sendToBlue.substr(i, 2), 16);
			}
			let buffer = uint8Array.buffer;

			const txlen = buffer.byteLength;
			if (this.deviceId && this.serviceId && this.characteristicId) {
				setTimeout(() => {
					uni.writeBLECharacteristicValue({
						deviceId: this.deviceId,
						serviceId: this.serviceId,
						characteristicId: this.characteristicId,
						value: buffer,
						success: (res) => {
							this.txCount += txlen;
							this.timTX += txlen;
							uni.showToast({
								title: "发送成功",
								icon: "none"
							});
						},
						fail: (error) => {
							console.error("发送失败", error);
							uni.showToast({
								title: "发送失败",
								icon: "none"
							});
						},
						complete: () => {
							this.sending = false;
						},
					});
				}, 100);
			} else {
				console.error("蓝牙设备信息不完整，无法发送数据");
				this.sending = false;
			}
		},
		gotoback() {
			if (this.device == null) {
				uni.navigateTo({
					url: "/blueTooth/findBluetooth/findBluetooth"
				});
				return;
			}
			clearTimeout(this.timer);
			uni.closeBLEConnection({
				deviceId: this.deviceId
			});
			this.connected = false;
			uni.navigateBack({
				delta: 1
			});
		},
		godisconnect() {
			if (this.connected) {
				uni.closeBLEConnection({
					deviceId: this.deviceId
				});
				this.connected = false;
				this.reconnect = "重新连接";
				this.connectState = "已断开";
				uni.setNavigationBarTitle({
					title: "已断开 " + this.device.name
				});
				this.showModalTips(this.device.name + "已断开连接...");
			} else {
				uni.setNavigationBarTitle({
					title: "正在连接 " + this.device.name
				});
				this.connectState = "正在连接";
				this.reconnect = "连接中...";
				uni.createBLEConnection({
					deviceId: this.deviceId,
					success: (res) => {
						this.connected = true;
						this.connectState = "读取服务";
						this.reconnect = "断开连接";
						this.recdata = "";
						this.rxCount = 0;
						this.txCount = 0;
						uni.setNavigationBarTitle({
							title: "已连接 " + this.device.name
						});
						this.getBLEDeviceServices(this.deviceId);
					},
				});
			}
		},
		connectToDevice(deviceId) {
			this.loading = true;
			this.serviceu = getApp().globalData.mserviceuuid.toUpperCase();
			this.txdu = getApp().globalData.mtxduuid.toUpperCase();
			this.rxdu = getApp().globalData.mrxduuid.toUpperCase();
			this.deviceId = deviceId;
			uni.setNavigationBarTitle({
				title: "正在连接 " + deviceId
			});
			uni.createBLEConnection({
				deviceId,
				success: (res) => {
					this.connected = true;
					this.connectState = "读取服务";
					this.reconnect = "断开连接";
					uni.setNavigationBarTitle({
						title: "已连接 " + deviceId
					});
					this.getBLEDeviceServices(deviceId);
				},
				complete: () => {
					this.loading = false;
				},
			});
		},
		getBLEDeviceServices(deviceId) {
			this.readyRec = false;
			uni.getBLEDeviceServices({
				deviceId,
				success: (res) => {
					let isService = res.services.some(
						(service) => this.serviceu === service.uuid
					);
					if (isService) {
						this.getBLEDeviceCharacteristics(
							deviceId,
							res.services.find((service) => this.serviceu === service.uuid).uuid
						);
						this.connectState = "获取特征值";
					} else {
						this.connectState = "UUID错误";
						this.showModalTips(
							this.serviceu + "找不到目标服务UUID 请确认UUID是否设置正确或重新连接"
						);
					}
				},
			});
		},
		getBLEDeviceCharacteristics(deviceId, serviceId) {
			uni.getBLEDeviceCharacteristics({
				deviceId,
				serviceId,
				success: (res) => {
					res.characteristics.forEach((item) => {
						if (item.properties.read) {
							uni.readBLECharacteristicValue({
								deviceId,
								serviceId,
								characteristicId: item.uuid,
							});
						}
						if (item.properties.write && this.txdu === item.uuid) {
							this.characteristicId = item.uuid;
							this.serviceId = serviceId;
						}
						if ((item.properties.notify || item.properties.indicate) && this.rxdu ===
							item.uuid) {
							uni.notifyBLECharacteristicValueChange({
								deviceId,
								serviceId,
								characteristicId: item.uuid,
								state: true,
								success: () => {
									this.connectState = "连接成功";
									this.readyRec = true;
								},
							});
						}
					});
				},
			});
			// 监听蓝牙特征值变化
			uni.onBLECharacteristicValueChange((characteristic) => {
				// 如果当前特征值id与rxdu不相等，或者没有准备好接收数据，则返回
				if (this.rxdu !== characteristic.characteristicId || !this.readyRec) return;
				// 将特征值转换为十六进制字符串
				const mrecstr = this.hexRec ? this.ab2hex(characteristic.value) : this.ab2Str(characteristic
					.value);
				// 如果接收到的数据长度超过3000，则只保留最新的数据
				if (this.recdata.length > 3000) {
					this.recdata = this.recdata.substring(mrecstr.length);
				}
				// 将接收到的数据添加到recdata中
				this.recdata += mrecstr;
				// 计算接收到的数据长度
				this.rxCount += characteristic.value.byteLength;
				// 计算接收到的数据总长度
				this.timRX += characteristic.value.byteLength;
			});
		},
		showModalTips(str) {
			this.showTips = str;
			const animation = uni.createAnimation({
				duration: 200,
				timingFunction: "linear",
				delay: 0,
			});
			this.animation = animation;
			animation.translateY(300).step();
			this.animationData = animation.export();
			this.showModalStatus = true;
			setTimeout(() => {
				animation.translateY(0).step();
				this.animationData = animation.export();
			}, 200);
			setTimeout(() => {
				this.hideModalTips();
			}, 2000);
		},
		hideModalTips() {
			const animation = uni.createAnimation({
				duration: 200,
				timingFunction: "linear",
				delay: 0,
			});
			this.animation = animation;
			animation.translateY(300).step();
			this.animationData = animation.export();
			setTimeout(() => {
				animation.translateY(0).step();
				this.animationData = animation.export();
				this.showModalStatus = false;
			}, 200);
		},
		ab2hex(buffer) {
			return Array.prototype.map
				.call(new Uint8Array(buffer), (bit) => ("00" + bit.toString(16)).slice(-2) + " ")
				.join("")
				.toUpperCase();
		},
		ab2Str(arrayBuffer) {
			return String.fromCharCode.apply(null, new Uint8Array(arrayBuffer));
		},
		joint() {
			return `0011223344${this.bluetoothSwitch ? "A5" : "A6"}${this.hexadecimal}64123456780011223344556677`;
		},
		readSetting() {
			const app = getApp();
			app.readSetting();
			const selectedDevice = uni.getStorageSync("device");
			const UUID = uni.getStorageSync("UUID");
			console.log("选择的设备", selectedDevice);
			// if (selectedDevice) {
			// 	this.deviceId = selectedDevice.deviceId;
			// 	this.deviceadd = "MAC " + this.deviceId;
			// } else if (UUID) {
			// 	this.deviceId = uni.getStorageSync("UUID");
			// }
			this.deviceId = selectedDevice.id;
			//判断是否是苹果
			if (uni.getSystemInfoSync().platform == 'ios') {
				this.deviceId = selectedDevice.IOSUUID;
			} else {
				this.deviceId = selectedDevice.UUID;
			}

		},
		saveSetting(time, text) {
			const app = getApp();
			app.saveSetting(time, text);
		},
	},
	mounted() {
		this.readSetting();
		this.Countdown();
		if (this.deviceId) {
			this.connectToDevice(this.deviceId);
		}
	},
	beforeDestroy() {
		this.saveSetting(this.autoSendInv, this.sendText);
		if (this.connected) {
			uni.closeBLEConnection({
				deviceId: this.deviceId
			});
			this.connected = false;
		}
	},
};
</script>


<style>
/* 基本页面样式 */
page {
	color: #333;
}

.btn-controll {
	display: flex;
	justify-content: space-between;
	align-items: center;
}

.leftBtn,
.rightBtn {
	font-size: 40rpx;
	flex: 1;
	background-color: #2ba245;
	margin: 5px;
}

/* 充值界面样式 */
.recharge {
	margin-top: 20px;
}

.recharge-title {
	font-size: 18px;
	font-weight: bold;
}

.recharge-input {
	margin-top: 10px;
}

.recharge-buttons {
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-start;
	margin-top: 10px;
}

.recharge-button {
	margin: 5px;
	padding: 10px;
	border: 1px solid #ddd;
	border-radius: 5px;
	background-color: #2ba245;
	font-size: 15px;
	flex: 1 1 30%;
	max-width: 30%;
	box-sizing: border-box;
}

.recharge-button.selected {
	background-color: #00b26a;
}

.button_sp {
	margin: 5px;
	background-color: #2ba245;
	color: #fff;
	font-size: 15px;
}

.layout_horizontal {
	display: flex;
	flex-direction: row;
}

.loading-overlay {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: rgba(0, 0, 0, 0.5);
	display: flex;
	justify-content: center;
	align-items: center;
	z-index: 1000;
}

.loading-spinner {
	border: 12px solid #f3f3f3;
	border-radius: 50%;
	border-top: 12px solid #3498db;
	width: 60px;
	height: 60px;
	animation: spin 2s linear infinite;
}

@keyframes spin {
	0% {
		transform: rotate(0deg);
	}

	100% {
		transform: rotate(360deg);
	}
}

.modal-mask {
	width: 100%;
	height: 100%;
	position: fixed;
	top: 0;
	left: 0;
	background: #000;
	opacity: 0.5;
	overflow: hidden;
	z-index: 9000;
	color: #fff;
}

.modal-dialog {
	width: 540rpx;
	overflow: hidden;
	position: fixed;
	top: 50%;
	left: 0;
	z-index: 9999;
	background: #f9f9f9;
	margin: -180rpx 105rpx;
	border-radius: 36rpx;
}

.modal-title {
	padding-top: 50rpx;
	font-size: 36rpx;
	color: #030303;
	text-align: center;
}

.modal-content {
	padding: 50rpx 32rpx;
}

.modal-footer {
	display: flex;
	flex-direction: row;
	height: 86rpx;
	border-top: 1px solid #dedede;
	font-size: 34rpx;
	line-height: 86rpx;
}

.btn-cancel {
	width: 50%;
	color: #333;
	text-align: center;
	border-right: 1px solid #dedede;
}

.btn-confirm {
	width: 50%;
	color: #10b7ff;
	text-align: center;
}

.dataShow {
	padding: 10px;
}

.data-box {
	border: 1px black solid;
	height: 100px;
	padding: 10px;
	overflow-y: scroll;
	background-color: #f9f9f9;
	word-wrap: break-word;
}
</style>